package com.yunpeng.aidevice.dao.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yunpeng.aidevice.common.constant.ConfigConstantValues;
import com.yunpeng.aidevice.common.dto.save.DeviceNoticeParameterSaveDTO;
import com.yunpeng.aidevice.common.dto.save.NoticeUserSaveDTO;
import com.yunpeng.aidevice.common.dto.save.ScriptParameterSaveDTO;
import com.yunpeng.aidevice.common.enums.ResultCodeEnum;
import com.yunpeng.common.exception.BizException;
import com.yunpeng.aidevice.dao.mapper.record.NoticeConfigMapper;
import com.yunpeng.aidevice.dao.mapper.record.NoticeRuleParameterMapper;
import com.yunpeng.aidevice.dao.mapper.record.RuleScriptMapper;
import com.yunpeng.aidevice.dao.model.entity.DeviceDO;
import com.yunpeng.aidevice.dao.model.entity.UserDO;
import com.yunpeng.aidevice.dao.model.record.DictionariesDO;
import com.yunpeng.aidevice.dao.model.record.NoticeConfigDO;
import com.yunpeng.aidevice.dao.model.record.NoticeRuleParameterDO;
import com.yunpeng.aidevice.dao.model.record.RuleScriptDO;
import com.yunpeng.aidevice.dao.service.IDeviceService;
import com.yunpeng.aidevice.dao.service.IDictionariesService;
import com.yunpeng.aidevice.dao.service.INoticeRuleService;
import com.yunpeng.aidevice.dao.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * NoticeRuleServiceImpl
 *
 * @author : Moore(hemw)
 * @date : 2020-04-28
 */
@Service
public class NoticeRuleServiceImpl implements INoticeRuleService {

    /**
     * 日志对象
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(NoticeRuleServiceImpl.class);
    @Resource
    private RuleScriptMapper ruleScriptMapper;

    @Resource
    private IDictionariesService dictionariesService;

    @Resource
    private NoticeRuleParameterMapper noticeRuleParameterMapper;

    @Resource
    private NoticeConfigMapper noticeConfigMapper;

    @Resource
    private IUserService userService;

    @Resource
    private IDeviceService deviceService;

    @Override
    /**
     * 通知规则的下拉列表
     *
     * @return
     */
    public JSONArray ruleDropdownList() {
        Map<String, Object> queryMap = new HashMap<>(16);
        queryMap.put("flag", 1);
        List<RuleScriptDO> ruleScriptDOList = ruleScriptMapper.queryForList(queryMap);
        JSONArray result = new JSONArray();
        if (ruleScriptDOList != null) {
            for (RuleScriptDO ruleScriptDO : ruleScriptDOList) {
                JSONObject item = new JSONObject();
                item.put("scriptName", ruleScriptDO.getRuleName());
                item.put("scriptCode", ruleScriptDO.getRuleCode());
                result.add(item);
            }
        }
        return result;
    }

    @Override
    /**
     * 获取规则的参数下拉菜单列表
     *
     * @param scriptCodes 脚本代码集合
     * @param deviceCode  需要设置提醒的设备代码
     * @return
     */
    public JSONArray ruleParameterDropdownList(List<String> scriptCodes, String deviceCode) {
        JSONArray result = new JSONArray();
        if (scriptCodes == null || scriptCodes.isEmpty()) {
            return result;
        }
        List<DictionariesDO> dictionariesDOList = dictionariesService.getByGroupList(ConfigConstantValues.RULE_PARAMETER_DOMAIN, scriptCodes);
        if (dictionariesDOList == null || dictionariesDOList.isEmpty()) {
            return result;
        }
        List<NoticeRuleParameterDO> noticeRuleParameterDOList = new ArrayList<>();
        if (StringUtils.isNotBlank(deviceCode)) {
            noticeRuleParameterDOList = noticeRuleParameterMapper.getByDeviceRuleCodes(deviceCode, scriptCodes);
        }
        //匹配设置已有值
        for (DictionariesDO dictionariesDO : dictionariesDOList) {
            JSONObject item = new JSONObject();
            item.put("scriptCode", dictionariesDO.getKeyGroup());
            item.put("parameterName", dictionariesDO.getKeyName());
            item.put("parameterComment", dictionariesDO.getKeyComment());
            item.put("parameterType", dictionariesDO.getKeyValue());
            for (NoticeRuleParameterDO noticeRuleParameterDO : noticeRuleParameterDOList) {
                if (noticeRuleParameterDO.getParameterName().equals(dictionariesDO.getKeyName()) &&
                        noticeRuleParameterDO.getRuleCode().equals(dictionariesDO.getKeyGroup())) {
                    item.put("parameterValue", noticeRuleParameterDO.getParameterValue());
                    break;
                }
            }
            result.add(item);
        }
        return result;
    }

    @Override
    /**
     * 删除设备的用户提醒设置
     *
     * @param deviceCode 设备代码
     * @param userCode   用户代码
     * @param scriptCode 规则代码
     * @return
     */
    public Boolean deletedDeviceNoticeUser(String deviceCode, String userCode, String scriptCode) {
        if (StringUtils.isBlank(deviceCode)) {
            return false;
        }
        if (StringUtils.isBlank(userCode)) {
            return false;
        }
        if (StringUtils.isBlank(scriptCode)) {
            return false;
        }
        noticeConfigMapper.deleteDeviceNoticeUser(userCode, deviceCode, Collections.singletonList(scriptCode));
        return true;
    }

    @Override
    /**
     * 设备的报警用户列表
     *
     * @param deviceCode 设备代码
     * @return
     */
    public List<NoticeConfigDO> deviceNoticeUserList(String deviceCode) {
        if (StringUtils.isBlank(deviceCode)) {
            return new ArrayList<>();
        }
        Map<String, Object> queryMap = new HashMap<>(16);
        queryMap.put("flag", 1);
        queryMap.put("device_code", deviceCode);
        return noticeConfigMapper.queryForList(queryMap);
    }

    @Override
    /**
     * 新增提醒用户
     *
     * @param noticeUserSaveDTO 提醒用户信息
     * @param operatorCode      操作人代码
     * @return
     */
    public Boolean addNoticeToUser(NoticeUserSaveDTO noticeUserSaveDTO, String operatorCode) {
        if (noticeUserSaveDTO == null || noticeUserSaveDTO.getDeviceCode() == null || noticeUserSaveDTO.getUserCode() == null
                || noticeUserSaveDTO.getScripts() == null || noticeUserSaveDTO.getScripts().isEmpty()) {
            return false;
        }
        UserDO userDO = userService.getByCode(noticeUserSaveDTO.getUserCode(), noticeUserSaveDTO.getMerchantCode(), noticeUserSaveDTO.getTenantCode());
        if (userDO == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "无此用户");
        }
        DeviceDO deviceDO = deviceService.getByCode(noticeUserSaveDTO.getDeviceCode(), noticeUserSaveDTO.getMerchantCode(), noticeUserSaveDTO.getTenantCode());
        if (deviceDO == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "无此设备");
        }
        List<NoticeConfigDO> saveNoticeConfigList = new ArrayList<>();

        //处理主记录
        List<RuleScriptDO> ruleScriptDOList = ruleScriptMapper.getByRuleCodes(noticeUserSaveDTO.getScripts());
        for (RuleScriptDO script : ruleScriptDOList) {
            NoticeConfigDO noticeConfigDO = new NoticeConfigDO();
            noticeConfigDO.initForNew(operatorCode);
            noticeConfigDO.setOrgName(userDO.getOrganizationName());
            noticeConfigDO.setOrgCode(userDO.getOrganizationCode());
            noticeConfigDO.setPhone(userDO.getPhone());
            noticeConfigDO.setEmail(userDO.getEmail());
            noticeConfigDO.setPhoneMsgNotice(noticeUserSaveDTO.getPhoneMsg());
            noticeConfigDO.setEmailNotice(noticeUserSaveDTO.getEmail());
            noticeConfigDO.setUserCode(userDO.getCode());
            noticeConfigDO.setUserName(userDO.getName());
            noticeConfigDO.setRuleCode(script.getRuleCode());
            noticeConfigDO.setRuleName(script.getRuleName());
            noticeConfigDO.setDeviceCode(deviceDO.getCode());
            saveNoticeConfigList.add(noticeConfigDO);
        }
        try {
            noticeConfigMapper.batchAdd(saveNoticeConfigList);
            return true;
        } catch (Exception ex) {
            LOGGER.error("save notice config info error : {}", noticeUserSaveDTO, ex);
            throw new BizException(ResultCodeEnum.SAVE_DATA_FAILED);
        }
    }

    @Override
    /**
     * 配置设备提醒参数
     *
     * @param deviceNoticeParameterSaveDTO 设备提醒参数信息
     * @param operatorCode                 操作人代码
     * @return
     */
    public Boolean configDeviceNoticeParameters(DeviceNoticeParameterSaveDTO deviceNoticeParameterSaveDTO, String operatorCode) {
        if (deviceNoticeParameterSaveDTO == null || deviceNoticeParameterSaveDTO.getDeviceCode() == null
                || deviceNoticeParameterSaveDTO.getScripts() == null || deviceNoticeParameterSaveDTO.getScripts().isEmpty()) {
            return false;
        }
        DeviceDO deviceDO = deviceService.getByCode(deviceNoticeParameterSaveDTO.getDeviceCode(), deviceNoticeParameterSaveDTO.getMerchantCode(), deviceNoticeParameterSaveDTO.getTenantCode());
        if (deviceDO == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "无此设备");
        }
        List<NoticeRuleParameterDO> saveNoticeRuleParameterList = new ArrayList<>();
        //处理参数
        if (deviceNoticeParameterSaveDTO.getParameters() == null) {
            deviceNoticeParameterSaveDTO.setParameters(new ArrayList<>());
        }
        List<RuleScriptDO> ruleScriptDOList = ruleScriptMapper.getByRuleCodes(deviceNoticeParameterSaveDTO.getScripts());
        for (ScriptParameterSaveDTO parameter : deviceNoticeParameterSaveDTO.getParameters()) {
            Optional<RuleScriptDO> ruleScriptOptional = ruleScriptDOList.stream().filter(t -> t.getRuleCode().equals(parameter.getScriptCode())).findFirst();
            if (!ruleScriptOptional.isPresent()) {
                continue;
            }
            NoticeRuleParameterDO noticeRuleParameterDO = new NoticeRuleParameterDO();
            noticeRuleParameterDO.initForNew(operatorCode);
            noticeRuleParameterDO.setDeviceCode(deviceDO.getCode());
            noticeRuleParameterDO.setRuleCode(parameter.getScriptCode());
            noticeRuleParameterDO.setParameterName(parameter.getParameterName());
            noticeRuleParameterDO.setParameterValue(parameter.getParameterValue());
            saveNoticeRuleParameterList.add(noticeRuleParameterDO);
        }
        noticeRuleParameterMapper.deleteDeviceRuleParameter(deviceDO.getCode(), deviceNoticeParameterSaveDTO.getScripts());
        if (saveNoticeRuleParameterList.size() > 0) {
            noticeRuleParameterMapper.batchAdd(saveNoticeRuleParameterList);
        }
        return true;
    }

    @Override
    /**
     * 获取指定的设备规则参数值
     *
     * @param deviceCode
     * @param ruleName
     * @param parameterName
     * @return
     */
    public NoticeRuleParameterDO getDeviceNoticeRuleParameter(String deviceCode, String ruleName, String parameterName) {
        return noticeRuleParameterMapper.getByDeviceParameter(deviceCode, ruleName, parameterName);
    }

}
